package com.ruoyi.web.controller.mobile;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisUtils;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.mobile.service.IWechatService;
import com.ruoyi.system.mapper.SysUserMapper;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;


@Controller
@RequestMapping("/wechat")
public class WechatController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IWechatService wechatService;

    private String appid = "wx4690c38b14ca8dc3";

    private String secret = "2d36ad79456c90a7a82b89af156380cc";

    private String redirectUrl = "https://admin2.bravo.love/prod-api/wechat/accessToken";

    private String loginRedirectUrl = "https://admin2.bravo.love/prod-api/wechat/accessTokenLogin";

    private String wechatLoginUrl = "https://admin2.bravo.love/wechatlogin?token=";

    /******************************** 微信公众号 start ******************************************/
    /**
     * 绑定微信账号
     * @param id 用户id
     * @param response
     */
    @GetMapping("/bindwechat/{id}")
    public void bindWechat(@PathVariable("id") Integer id, HttpServletResponse response) throws IOException {
        String state = RandomUtil.randomString(12);
        //缓存用户id
        redisUtils.set(state,id,600L);
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_base&state=" + state + "#wechat_redirect";
        response.sendRedirect(url);
    }

    /**
     * 绑定微信账号时从微信返回的url
     * @param code
     * @param state
     * @return
     */
    @GetMapping("/accessToken")
    public String accessToken(@RequestParam(name = "code") String code, @RequestParam(name = "state") String state) {
        //code=CODE&state=STATE
        Long userId = ((Integer) redisUtils.get(state)).longValue();
        if (userId == null || StrUtil.isBlank(code)) {
            return "error";
        }
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) { // 判断是否成功
                //检查用户是否已经绑定过了
                SysUser sysUser = sysUserMapper.selectUserById(userId);
                if (!StrUtil.isBlank(sysUser.getOpenid())) {
                    System.out.println("已经绑定过微信: " + userId);
                    return "error";
                }
                String string = response.body().string();
                ObjectMapper mapper = new ObjectMapper();
                mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                Map<String, Object> map = mapper.readValue(string, Map.class);
                String openid = (String) map.get("openid");
                // userId 和 opendid 关联起来
                sysUserMapper.updateOpenidByUserId(userId, openid);
                return "success";
            } else {
                return "error";
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return "error";
        }
    }

    /**
     * 使用微信来登录
     * @param response
     * @throws IOException
     */
    @GetMapping("/login")
    public void wechatLogin(HttpServletResponse response) throws IOException {
        String state = RandomUtil.randomString(12);
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + loginRedirectUrl + "&response_type=code&scope=snsapi_base&state=" + state + "#wechat_redirect";
        response.sendRedirect(url);
    }

    @GetMapping("/accessTokenLogin")
    public void accessTokenLogin(@RequestParam(name = "code") String code, @RequestParam(name = "state") String state, HttpServletResponse res) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) { // 判断是否成功
                String string = response.body().string();
                ObjectMapper mapper = new ObjectMapper();
                mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                Map<String, Object> map = mapper.readValue(string, Map.class);
                String openid = (String) map.get("openid");
                SysUser user = sysUserMapper.selectUserByOpenid(openid);
                if (StringUtils.isNull(user)) {
                    throw new ServiceException("登录用户不存在");
                } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
                    throw new ServiceException("对不起，您的账号已被删除");
                } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
                    throw new ServiceException("对不起，您的账号已停用");
                }
                LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
                String token = tokenService.createToken(loginUser);
                res.sendRedirect(wechatLoginUrl + token);
            } else {
                //todo 去到登录失败的界面
            }
        } catch (Exception e) {
            //todo 去到登录失败的界面
        }
    }


    /******************************** 微信公众号 end ******************************************/


    /******************************** 微信小程序 start ******************************************/


    @GetMapping("/mini")
    public void miniprogram(HttpServletResponse response) throws IOException {
        String url = (String) redisUtils.get(CacheConstants.WECHAT_MINIPROGRAM_URL);
        if (StrUtil.isBlank(url)) {
            url = wechatService.getUrlscheme();
            redisUtils.set(CacheConstants.WECHAT_MINIPROGRAM_URL, url, 2505600L);
        }
        response.sendRedirect(url);
    }

    /******************************** 微信小程序 end ******************************************/
//    @GetMapping("/test")
//    public void ttest( HttpServletResponse res) throws IOException {
//        String openid = "111";
//        SysUser user = sysUserMapper.selectUserByOpenid(openid);
//        if (StringUtils.isNull(user)) {
//            throw new ServiceException("登录用户不存在");
//        } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
//            throw new ServiceException("对不起，您的账号已被删除");
//        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
//            throw new ServiceException("对不起，您的账号已停用");
//        }
//        LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
//        String token = tokenService.createToken(loginUser);
//        res.sendRedirect("http://localhost/wechatlogin?token="+token);
//    }

}
